/**
 * 条件匹配器模块
 * 处理规则条件的匹配逻辑
 */
export class ConditionMatcher {
  constructor() {
    this.supportedOperators = [
      'equals', 'not_equals', 'contains', 'not_contains',
      'matches', 'starts_with', 'ends_with'
    ];
    
    this.supportedFields = [
      'url', 'method', 'status', 'headers', 'params', 'cookies'
    ];
  }

  /**
   * 检查规则是否匹配事务
   */
  async matchRule(rule, transaction) {
    if (!rule.conditions || rule.conditions.length === 0) {
      console.log(`📋 规则 ${rule.name} 无条件，匹配失败`);
      return false;
    }

    console.log(`🔍 开始匹配规则条件: ${rule.name}`);
    console.log(`📋 条件数量: ${rule.conditions.length}`);

    // 所有条件都必须匹配（AND逻辑）
    for (let i = 0; i < rule.conditions.length; i++) {
      const condition = rule.conditions[i];
      console.log(`🔍 检查条件 ${i + 1}/${rule.conditions.length}:`, condition);
      
      const isMatch = await this.matchCondition(condition, transaction);
      console.log(`🔍 条件 ${i + 1} 结果:`, isMatch ? '✅ 匹配' : '❌ 不匹配');
      
      if (!isMatch) {
        console.log(`❌ 规则条件匹配失败: ${rule.name}`);
        return false;
      }
    }

    console.log(`✅ 规则条件全部匹配: ${rule.name}`);
    return true;
  }

  /**
   * 检查单个条件是否匹配
   */
  async matchCondition(condition, transaction) {
    try {
      // 支持新的条件格式：{ value: "url 包含 app.", operator: "contains" }
      if (condition.value && typeof condition.value === 'string' && !condition.type) {
        return this.parseAndMatchCondition(condition.value, condition.operator || 'contains', transaction);
      }
      
      // 支持旧的条件格式：{ type: "url_contains", value: "/api/", operator: "contains" }
      return this.matchTypedCondition(condition, transaction);
      
    } catch (error) {
      console.error('❌ 条件匹配异常:', error.message);
      return false;
    }
  }

  /**
   * 匹配类型化条件（旧格式）
   */
  matchTypedCondition(condition, transaction) {
    const { type, field, value, operator = 'contains' } = condition;
    
    let targetValue = '';
    
    switch (type) {
      case 'url_contains':
      case 'url_matches':
        targetValue = transaction.request.url;
        break;
        
      case 'method_equals':
        targetValue = transaction.request.method;
        break;
        
      case 'header_contains':
        if (field && transaction.request.headers[field]) {
          targetValue = transaction.request.headers[field];
        }
        break;
        
      case 'status_code_equals':
        if (transaction.response) {
          targetValue = transaction.response.statusCode.toString();
        }
        break;
        
      default:
        console.warn(`⚠️ 不支持的条件类型: ${type}`);
        return false;
    }

    return this.compareValues(targetValue, value, operator);
  }

  /**
   * 解析并匹配新格式的条件
   */
  parseAndMatchCondition(conditionText, operator, transaction) {
    try {
      // 解析条件文本，例如：'url 包含 app.'
      const parts = conditionText.trim().split(/\s+/);
      if (parts.length < 3) {
        console.warn('⚠️ 条件格式不正确:', conditionText);
        return false;
      }
      
      const field = parts[0].toLowerCase(); // url, method, status等
      const operatorText = parts[1]; // 包含, 等于, 不包含等
      const expectedValue = parts.slice(2).join(' '); // 期望值
      
      // 获取目标值
      const targetValue = this.getFieldValue(field, transaction);
      if (targetValue === null) {
        console.warn(`⚠️ 无法获取字段值: ${field}`);
        return false;
      }
      
      // 根据操作符文本转换为标准操作符
      const standardOperator = this.normalizeOperator(operatorText, operator);
      
      console.log(`🔍 条件详情: ${field}="${targetValue}" ${standardOperator} "${expectedValue}"`);
      
      return this.compareValues(targetValue, expectedValue, standardOperator);
      
    } catch (error) {
      console.error('❌ 解析条件失败:', error.message);
      return false;
    }
  }

  /**
   * 获取指定字段的值
   */
  getFieldValue(field, transaction) {
    switch (field) {
      case 'url':
        return transaction.request.url;
        
      case 'method':
        return transaction.request.method;
        
      case 'status':
        return transaction.response ? transaction.response.statusCode.toString() : null;
        
      default:
        // 检查是否是headers.xxx格式
        if (field.startsWith('headers.')) {
          const headerName = field.substring(8);
          return transaction.request.headers[headerName] || null;
        } 
        
        // 检查是否是params.xxx格式
        if (field.startsWith('params.')) {
          const paramName = field.substring(7);
          return (transaction.request.params && transaction.request.params[paramName]) || null;
        } 
        
        // 检查是否是cookies.xxx格式
        if (field.startsWith('cookies.')) {
          const cookieName = field.substring(8);
          return (transaction.request.cookies && transaction.request.cookies[cookieName]) || null;
        }
        
        console.warn('⚠️ 不支持的字段:', field);
        return null;
    }
  }

  /**
   * 标准化操作符
   */
  normalizeOperator(operatorText, fallbackOperator) {
    const operatorMap = {
      '包含': 'contains',
      '不包含': 'not_contains',
      '等于': 'equals',
      '=': 'equals',
      '不等于': 'not_equals',
      '!=': 'not_equals',
      '开始于': 'starts_with',
      '结束于': 'ends_with',
      '匹配': 'matches'
    };
    
    return operatorMap[operatorText] || fallbackOperator || 'contains';
  }

  /**
   * 值比较
   */
  compareValues(target, expected, operator) {
    if (!target && operator !== 'not_contains' && operator !== 'not_equals') {
      return false;
    }
    
    const targetStr = target ? target.toString().toLowerCase() : '';
    const expectedStr = expected.toString().toLowerCase();
    
    console.log(`🔍 比较值: "${targetStr}" ${operator} "${expectedStr}"`);
    
    switch (operator) {
      case 'equals':
        return targetStr === expectedStr;
        
      case 'not_equals':
        return targetStr !== expectedStr;
        
      case 'contains':
        return targetStr.includes(expectedStr);
        
      case 'not_contains':
        return !targetStr.includes(expectedStr);
        
      case 'matches':
        try {
          const regex = new RegExp(expectedStr, 'i');
          return regex.test(targetStr);
        } catch (error) {
          console.warn('⚠️ 正则表达式无效:', expectedStr);
          return false;
        }
        
      case 'starts_with':
        return targetStr.startsWith(expectedStr);
        
      case 'ends_with':
        return targetStr.endsWith(expectedStr);
        
      default:
        console.warn('⚠️ 不支持的操作符:', operator);
        return false;
    }
  }

  /**
   * 验证条件格式
   */
  validateCondition(condition) {
    const errors = [];
    
    if (!condition) {
      errors.push('条件不能为空');
      return errors;
    }
    
    // 检查新格式条件
    if (condition.value && typeof condition.value === 'string' && !condition.type) {
      const parts = condition.value.trim().split(/\s+/);
      if (parts.length < 3) {
        errors.push('条件格式不正确，应为 "字段 操作符 值"');
      }
      
      const field = parts[0].toLowerCase();
      if (!this.isValidField(field)) {
        errors.push(`不支持的字段: ${field}`);
      }
      
      if (condition.operator && !this.supportedOperators.includes(condition.operator)) {
        errors.push(`不支持的操作符: ${condition.operator}`);
      }
    }
    
    // 检查旧格式条件
    if (condition.type) {
      if (!condition.value) {
        errors.push('条件值不能为空');
      }
      
      if (condition.operator && !this.supportedOperators.includes(condition.operator)) {
        errors.push(`不支持的操作符: ${condition.operator}`);
      }
    }
    
    return errors;
  }

  /**
   * 检查字段是否有效
   */
  isValidField(field) {
    if (this.supportedFields.includes(field)) {
      return true;
    }
    
    // 检查嵌套字段
    const nestedPrefixes = ['headers.', 'params.', 'cookies.'];
    return nestedPrefixes.some(prefix => field.startsWith(prefix));
  }

  /**
   * 获取支持的操作符列表
   */
  getSupportedOperators() {
    return [...this.supportedOperators];
  }

  /**
   * 获取支持的字段列表
   */
  getSupportedFields() {
    return [...this.supportedFields];
  }
} 